package de.clue.corpus.twitter.langident;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.Collection;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

public class SaxFileReader extends org.xml.sax.helpers.DefaultHandler {

	private boolean foundText;
	private StringBuffer cachedTwitterText = new StringBuffer();
	private StringBuffer cachedText = new StringBuffer();
	private boolean foundGerman;
	private Writer out;
	private final String path;
	private final String textIdentMode;
	private final String outputPath;
    private ILanguageIdentification langIdent;

	
	public SaxFileReader(String path, String outputPath, String textIdentMode) throws Exception {
		this.path = path;
		this.outputPath = outputPath;
		this.textIdentMode = textIdentMode;
		
		 validateArguments();
		 
	}
	
	private void validateArguments() {
		
		if(outputPath == null){
			throw new IllegalArgumentException("outputPath must not be empty!");
		}
		
		File toCheck = new File(outputPath);
		if(!toCheck.exists()){
			toCheck.mkdirs();
			if(!toCheck.exists()) {
				throw new IllegalArgumentException("outputPath can not be created!");
				
			}
		}
		
		if(path == null){
			throw new IllegalArgumentException("path must not be empty!");
		}
		
		toCheck = new File(path);
		if(!toCheck.exists()){
			throw new IllegalArgumentException("path must exist!");
		}
		
		
	}


	
	
	public void process(){
		identifyFilesInDirectory();
		
	}
	
	
	private void identifyFilesInDirectory() {
		File sourceDirectory = new File(path);
		String[] list = sourceDirectory.list();
		Collection<File> listFiles = FileUtils.listFiles(sourceDirectory, new String[]{"xml"}, false);
		
		for (Iterator iterator = listFiles.iterator(); iterator.hasNext();) {
			try {
				File currentFile = (File) iterator.next();
				if(currentFile.isFile()){
					System.out.println("Processing file: " + currentFile.getAbsolutePath());
					
					try {
						out = new BufferedWriter(new OutputStreamWriter(
								new FileOutputStream(outputPath + System.getProperty("file.separator") + currentFile.getName()), "UTF8"));
						
						out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
						out.write("<root>");
						out.write(System.getProperty("line.separator"));
						
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					} catch (FileNotFoundException e) {
						e.printStackTrace();
					} catch (IOException e) {
						e.printStackTrace();
					}
					
					readFile(currentFile);
					
					try {
						out.write("</root>");
						out.flush();
						out.close();
						out = null;
					} catch (Exception e) {
						e.printStackTrace();
					}
					
					System.out.println("File checked!");
					
				}
			} catch (Exception e) {
				e.printStackTrace();
				
			}
			
		}
		
	}
	
	
	 private void readFile(File file) throws Exception{

	       // Factory um parser zu erzeugen
	       SAXParserFactory factory = SAXParserFactory.newInstance();
	       // Parser um datei zu parsen
	       SAXParser saxParser = factory.newSAXParser();

	       // Parse Datei; Parameter sind: Dateiname und Handler
	       saxParser.parse(file, this);

	   }


	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {

		if (qName.equalsIgnoreCase("root")) {
//			System.out.println(">>>> START <<<<<<<");
		}

		if (qName.equalsIgnoreCase("tweet")) {
			// System.out.println(" ### Tweet ###");
		}
		if (qName.equalsIgnoreCase("text")) {
			foundText = true;
		}


		cachedTwitterText.append("<" + qName + ">");

	}

	public void endElement(String uri, String localName, String name)
			throws SAXException {
		
		
		if("text".equals(name)){
			foundText = false;
			
	           // (!!!!!!!!!!!!!!)hier unten die Erkennung der sprache: 
			long timestart = System.currentTimeMillis();
			String text = cachedText.toString();
			cachedText = new StringBuffer();
			
			// cheat a little - skip all which apparently don't have smiles :-)
			Pattern all =
			        Pattern.compile
			        ("[o>}\\])]? # hair, optional \n" +
			                "[:;8x] # eyes \n" +
			                "[',]? # subeyes, optional \n" +
			                "-? # nose, optional \n" +
			                "(?: [sdpco\\#@*$|] " +
			                " | \\)\\)? " +
			                " | \\(\\(? ) # mouth \n" +
			                "=? # beard, optional \n",
			                Pattern.COMMENTS | Pattern.CASE_INSENSITIVE);
			Matcher m = all.matcher(text);
			if(m.find()){
			    System.out.print("Check ... ");
			    langIdent = new LangIdentTextCat();
			    String language = langIdent.getLanguage(text);
			    int distancesDeviation = langIdent.getDistancesDeviation();
			    if("german".equals(language) && distancesDeviation > 7000){ // TODO get number from commandline
			        foundGerman = true;
			        System.out.print("Found!");
			    }
			    System.out.print("\n");
			    
			}
			// cheat a little - skip all which apparently don't have smiles :-)
	           
	           
	           long timeend = System.currentTimeMillis();
	            
               //long delta = timeend - timestart;
               //System.out.println("Delta: " + delta);
	          
	           
		}

		cachedTwitterText.append("</" + name + ">");

		if ("tweet".equals(name)) {
			if (foundGerman) {
				appendToFile(cachedTwitterText.toString());

			}
			cachedTwitterText = null;
			cachedTwitterText = new StringBuffer();
			foundGerman = false;
		}

	}
	
	 public void characters(char[] ch, int start, int length) throws SAXException {

	       // den Text des Elements
	       String text = new String(ch, start, length);

	       if (foundText){
	           cachedText.append(text);
	           
	       }
	       
	       text = escapeText(text);
	       cachedTwitterText.append(text);
	    }
	
	 
	 private String escapeText(String text){
			String escapedText = "";
			
			escapedText = text.replaceAll("&", "&amp;");
			escapedText = escapedText.replaceAll("\\<", "&lt;");
			escapedText = escapedText.replaceAll("\\>", "&gt;");
			escapedText = escapedText.replaceAll("\"", "&quot;");
			escapedText = escapedText.replaceAll("'", "&apos;");
			
//			escapedText = StringEscapeUtils.escapeXml(text);
			
			
			return escapedText;
			
		}
	
	private void appendToFile(String text) {
		
		   try {
				
				out.write(text);
//				out.write(System.getProperty("line.separator"));
			} catch (UnsupportedEncodingException e) {
			} catch (IOException e) {
			} 
		
	   }

}
